package org.cying.main.controller;

import cn.hutool.http.HttpStatus;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import lombok.extern.slf4j.Slf4j;
import org.cying.main.domain.SampleResult;
import org.cying.main.domain.Student;
import org.cying.main.handler.GlobalFlowHandler;
import org.cying.main.handler.StudentFlowHandler;
import org.cying.main.service.StudentService;
import org.cying.main.util.RsaUtil;
import org.cying.main.util.StudentUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * Student Server 控制类
 * @author Cying
 */
@Slf4j
@RefreshScope
@RestController
@RequestMapping(value = "/stu")
public class StudentController {

    @Resource
    private StudentService service;

    @Value("${cying.private-key}")
    private String privateKey;


    /**
     * 根据 type 对学生信息进行更新
     * @param type {0 - password, 3 - college, 4 - sid, 5 - birth, 6 - qq, 7 - tel}
     * @param value 要更新的值
     * @param sid 要更新的学生学号
     * @return 更新结果
     */
    @PatchMapping(value = "/alter/info")
    @SentinelResource(
            value = "alter-info",
            blockHandlerClass = StudentFlowHandler.class,
            blockHandler = "updateInfoHandler"
    )
    public SampleResult<String> alterInfo(
            @RequestParam(value = "type", required = true) Integer type,
            @RequestParam(value = "value", required = true) Object value,
            @RequestParam(value = "sid", required = true) String sid
    ) {
        Long id = RsaUtil.parseSid(sid, privateKey);
        System.out.println(id);
        System.out.println(RsaUtil.dencrypt(String.valueOf(value), privateKey));
        try {

            int res = 1;
//            switch (type) {
//                case 0:
//                    res = service.updateInfo(type, RsaUtil.dencrypt(String.valueOf(value), privateKey), id);
//                    break;
//                case 4:
//                    res = service.updateInfo(type, RsaUtil.parseSid(String.valueOf(value), privateKey), id);
//                    break;
//                default:
//                    res = service.updateInfo(type, value, id);
//            }
            return res == 1
                    ? new SampleResult<>("/stu/update-info", HttpStatus.HTTP_OK, null, "更新成功")
                    : new SampleResult<>("/stu/update-info", HttpStatus.HTTP_NOT_ACCEPTABLE, null, "更新失败");
        } catch (Exception e) {
            String msg = type == 4 ? "更新失败" : "学号已存在";
            return new SampleResult<>("/stu/update-info", HttpStatus.HTTP_NOT_ACCEPTABLE, e.getMessage(), msg);
        }
    }

    /**
     * 将最近签到日期设置为今天，避免查询签到时被重复检索到
     * @param sid 学号
     * @see org.cying.main.feign.SignFeignStudent
     * @return 更新结果
     */
    @PatchMapping(value = "/alter/last-sign")
    @SentinelResource(
            value = "last-sign",
            blockHandlerClass = GlobalFlowHandler.class,
            blockHandler = "flowHandler_l"

    )
    public SampleResult<Object> alterLastSign(
            @RequestParam("sid") String sid
    ) {
        Long id = RsaUtil.parseSid(sid, privateKey);
        int flag = service.updateLastSign(id);
        return flag == 1
                ? new SampleResult<>("/stu/alter/last-sign", HttpStatus.HTTP_OK, null)
                : new SampleResult<>("/stu/alter/last-sign", HttpStatus.HTTP_NOT_ACCEPTABLE, null);
    }

    /**
     * 验证学号和密码是否正确
     * @param sid 学号
     * @param passwd 加密过的密码
     * @return 验证结果
     */
    @GetMapping(value = "/auth/login")
    @SentinelResource(
            value = "auth-login",
            blockHandlerClass = StudentFlowHandler.class,
            blockHandler = "loginHandler"
    )
    public SampleResult<Student> authLogin(
            @RequestParam(value = "sid", required = true) String sid,
            @RequestParam(value = "passwd", required = true) String passwd,
            HttpServletResponse response
    ) {
        Long id = RsaUtil.parseSid(sid, privateKey);
        passwd = RsaUtil.dencrypt(passwd, privateKey);
        Student stu = service.authPasswd(id, passwd);
        if (stu != null && stu.getSid().equals(id)) {
            log.info(stu.getName() + "登录成功");
            Cookie cookie = new Cookie("Token", sid);
            cookie.setPath("/");
            cookie.setMaxAge(3 * 60);
            response.addCookie(cookie);
            return new SampleResult<>("/stu/auth/login", HttpStatus.HTTP_OK, stu, "登录成功");
        }
        return new SampleResult<>("/stu/auth/login", HttpStatus.HTTP_NOT_ACCEPTABLE, null, "登录失败");
    }

    /**
     * 根据给定信息, 新增一条学生信息
     * @param sid 学号
     * @param name 姓名
     * @param department 部门
     * @param group 组别/职位
     * @param college 值班时间
     * @return 创建结果
     */
    @PostMapping(value = "/create/record")
    @SentinelResource(
            value = "create-record",
            blockHandlerClass = StudentFlowHandler.class,
            blockHandler = "insertStuHandler"
    )
    public SampleResult<Object> createRecord(
            @RequestParam(value = "sid", required = true) String sid,
            @RequestParam(value = "name", required = true) String name,
            @RequestParam(value = "department", required = true) String department,
            @RequestParam(value = "group", required = true) String group,
            @RequestParam(value = "college", required = true) String college
    ) {
        Long SID = RsaUtil.parseSid(sid, privateKey);
        name = RsaUtil.dencrypt(name, privateKey);
        return service.insertStudent(SID, name, college, department, group)
                ? new SampleResult<>("/stu/create/record", HttpStatus.HTTP_OK, null, "注册成功")
                : new SampleResult<>("/stu/create/record", HttpStatus.HTTP_NOT_ACCEPTABLE, null, "学号 " + SID + " 已注册过");
    }

    @DeleteMapping(value = "/delete/record")
    public SampleResult<Boolean> deleteRecord(
            @RequestParam(value = "sid",        required = false) String sid,
            @RequestParam(value = "department", required = false) String department,
            @RequestParam(value = "group",      required = false) String group
    ) {
        Long SID = RsaUtil.parseSid(sid, privateKey);
        return service.deleteStudent(SID, department, group)
                ? new SampleResult<>("/stu/delete/record", HttpStatus.HTTP_OK, true, "删除成功")
                : new SampleResult<>("/stu/delete/record", HttpStatus.HTTP_NOT_ACCEPTABLE, false, "删除失败");
    }

    /**
     * 根据给定部门或小组获取学生
     * @param dept 部门
     * @param group 小组/职位
     * @see org.cying.main.feign.TaskFeignStudent
     * @return 查询结果
     */
    @GetMapping(value = "/get/by-dept")
    @SentinelResource(
            value = "by-dept",
            blockHandlerClass = GlobalFlowHandler.class,
            blockHandler = "flowHandler_ss"
    )
    public SampleResult<List> getByDept(
            @RequestParam(value = "dept", required = true) String dept,
            @RequestParam(value = "group", required = false) String group
    ) {
        List<Student> stuList = service.getStuByDept(dept, group);
        return stuList == null
                ? new SampleResult<>("/stu/get/by-dept", HttpStatus.HTTP_NOT_ACCEPTABLE, null, "未查询到相关记录")
                : group == null
                    ? new SampleResult<>("/sut/get/by-dept", HttpStatus.HTTP_OK, StudentUtils.parseToGroup(stuList))
                    : new SampleResult<>("/sut/get/by-dept", HttpStatus.HTTP_OK, stuList);
    }

    /**
     * 根据给定学号获取学生列表
     * @param sid 学号
     * @see org.cying.main.feign.SignFeignStudent
     * @see org.cying.main.feign.ClientFeignStudent
     * @return 查询结果
     */
    @GetMapping(value = "/get/by-sid")
    @SentinelResource(
            value = "by-sid",
            blockHandlerClass = GlobalFlowHandler.class,
            blockHandler = "flowHandler_l"
    )
    public SampleResult<List<Student>> getBySid(
            @RequestParam(value = "sid", required = false) String sid,
            @RequestParam(value = "sname", required = false) String name
    ) {
        Long SID = sid == null ? null : RsaUtil.parseSid(sid, privateKey);
        List<Student> stuList = service.getStuBySid(SID, name);
        return stuList.size() == 0
                ? new SampleResult<>("/stu/get/by-sid", HttpStatus.HTTP_NOT_ACCEPTABLE, null, "未查询到相关记录")
                : new SampleResult<>("/stu/get/by-sid", HttpStatus.HTTP_OK, stuList);
    }

    /**
     * 根据参数获取当前时间段待值班成员
     * @param time 当前时间段表达式
     * @see org.cying.main.feign.SignFeignStudent
     * @return 查询结果
     */
    @GetMapping(value = "/get/duty-list")
    @SentinelResource(
            value = "duty-list",
            blockHandlerClass = GlobalFlowHandler.class,
            blockHandler = "flowHandler_s"
    )
    public SampleResult<List<Student>> getDutyList(
        @RequestParam(value = "time", required = true) String time
    ) {
        return new SampleResult<>("/stu/get/duty-list", HttpStatus.HTTP_OK, service.getDutyList(time));
    }









}
